package com.sz.biz.logistics.core.service;

import com.sz.biz.common.customer.dto.CusUserAddressDto;
import com.sz.biz.logistics.core.dto.*;
import com.sz.biz.logistics.core.entity.Product;
import com.sz.biz.logistics.core.entity.ProductGroup;
import com.sz.biz.logistics.core.entity.ProductRegionRel;
import com.sz.biz.logistics.core.entity.ProductServiceRel;
import com.sz.common.base.dao.ParamData;
import com.sz.common.base.dto.QResultDto;
import com.sz.common.base.dto.QueryParams;
import com.sz.common.base.dto.ResultDto;
import com.sz.common.core.system.entity.SysDict;

import java.text.ParseException;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * Function: ProductService. <br>
 * Author: wentao.chang <br>
 * Date: 2017-04-24 10:08:00
 */
public interface ProductService {

    /**
     * 新增主信息
     *
     * @param product
     * @return
     * @throws ParseException
     */
    ProductDto save(ProductDto product) throws ParseException;

    /**
     * 修改主信息
     *
     * @param uid
     * @param product
     * @return
     * @throws ParseException
     */
    ProductDto update(String uid, ProductDto product) throws ParseException;

    /**
     * 修改产品计重规则
     *
     * @param uid
     * @param product
     * @return
     * @throws ParseException
     */
    String updateWeightInfo(String uid, ProductDto product) throws ParseException;


    /**
     * 根据uid启用产品
     *
     * @param uid
     * @return
     * @throws ParseException
     */
    Integer online(String uid) throws ParseException;

    /**
     * 根据uid停用产品
     *
     * @param uid
     * @return
     * @throws ParseException
     */
    Integer offline(String uid) throws ParseException;


    /**
     * 根据uids删除实体
     *
     * @param uids uid集合
     */
    void batchdelete(List<String> uids);

    /**
     * 根据uid删除实体
     *
     * @param uid
     * @param date
     * @return
     */
    String delete(String uid, Date date);

    /**
     * 根据uid查询可用生效的实体
     *
     * @param uids
     * @return 查询出来的实体对象
     */
    List<Product> findActivedByUids(List<String> uids);

    /**
     * 根据uids返回短接口
     *
     * @param uids
     * @return
     */
    List<Product> findShortActivedByUids(List<String> uids);

    /**
     * 产品uid查询短接口
     *
     * @param uid
     * @return
     */
    Product findShortActivedByUid(String uid);

    /**
     * 产品ids短接口
     *
     * @param ids
     * @return
     */
    List<Product> findShortActivedByIds(List<Integer> ids);

    /**
     * 根据id查询短接口
     *
     * @param id
     * @return
     */
    Product findShortActivedById(Integer id);

    /**
     * 根据uid查询可用生效的实体
     *
     * @param uid
     * @return
     */
    ProductDto findActivedByUid(String uid);

    /**
     * 根据主键Id查询单个实体
     *
     * @param id 主键id
     * @return 查询出来的实体对象
     */
    ProductDto findById(Integer id);

    /**
     * 根据主键Id查询单个实体-客户平台
     *
     * @param id 主键id
     * @return 查询出来的实体对象
     */
    ProductCustomerDto findByIdCustomer(Integer id);

    /**
     * 根据uid查询可用生效的实体
     *
     * @param uid  uid
     * @param time 时间点
     * @return 查询出来的实体对象
     */
    ProductDto findByUidAndTime(String uid, Date time);

    /**
     * 根据条件查询实体
     *
     * @param params 查询的参数集
     * @return 查询出的数据
     */
    QResultDto findByFilter(QueryParams params);

    /**
     * 根据条件查询实体-客户系统
     *
     * @param params 查询的参数集
     * @return 查询出的数据
     */
    QResultDto findByFilterCustomer(QueryParams params);

    /**
     * 异步校验产品名称
     *
     * @param uid
     * @param name
     * @return
     */
    void nameCheck(String uid, String name);

    /**
     * 异步校验产品编码
     *
     * @param ud
     * @param code
     */
    void codeCheck(String ud, String code);

    /**
     * 提交产品
     *
     * @param uids
     * @throws ParseException
     */
    void submit(List<String> uids) throws ParseException;

    /**
     * 审核产品
     *
     * @param uid
     * @param msg
     * @throws ParseException
     */
    void audit(String uid, String msg) throws ParseException;

    /**
     * 打回产品
     *
     * @param uid
     * @param msg
     */
    void reject(String uid, String msg);

    /**
     * 查询产品下的服务
     *
     * @param productUid
     * @param orderDate
     * @return
     */
    List<ProductServiceRel> findServicesByUidAndDate(String productUid, Date orderDate);

    /**
     * 查询产品下所有的服务
     *
     * @param productUid
     * @param orderDate
     * @param hasDisabled
     * @return
     */
    List<ProductServiceRel> findServiceDetailsByUidAndDate(String productUid, Date orderDate, boolean hasDisabled);

    /**
     * 按类型查询产品下的服务
     *
     * @param productUid
     * @param type
     * @param ordinal
     * @param hasDisabled
     * @param isMainInRequired
     * @return
     */
    List<ProductServiceRel> findProductServices(String productUid, String type, Integer ordinal, boolean hasDisabled, boolean isMainInRequired);


    List<ProductServiceTypeDto> findProductServiceTypes(String productUid, String type);

    /**
     * 根据主键Id查询产品下的所有服务
     *
     * @param productId
     * @return
     */
    List<Map> findServicesById(Integer productId);

    /**
     * 过滤起点终点范围内的产品
     *
     * @param fcountryStr  fcountryStr
     * @param fprovinceStr fprovinceStr
     * @param fcityStr     fcityStr
     * @param fareaStr     fareaStr
     * @param fstreetStr   fstreetStr
     * @param fpostcode    fpostcode
     * @param tcountryStr  tcountryStr
     * @param tprovinceStr tprovinceStr
     * @param tcityStr     tcityStr
     * @param tareaStr     tareaStr
     * @param tstreetStr   tstreetStr
     * @param tpostcode    tpostcode
     * @return
     */
    List<Product> findByRegion(String fcountryStr, String fprovinceStr, String fcityStr,
                               String fareaStr, String fstreetStr, String fpostcode,
                               String tcountryStr, String tprovinceStr, String tcityStr,
                               String tareaStr, String tstreetStr, String tpostcode);

    /**
     * 范围检查
     * @param uid
     * @param type
     * @param address
     * @return
     */
    //ResultDto checkRegion(String uid, String type, List<AddressDto> address);


    /**
     * 重量检查
     *
     * @param uid
     * @param weightDto
     * @return
     */
    ResultDto checkWeight(String uid, WeightDto weightDto);

    /**
     * 根据客户id检查范围
     *
     * @param uid
     * @param customerId
     * @param transportType public static final int TRANSPORT_SEA = 1;//海运地址
     *                      public static final int TRANSPORT_AIR = 6;//空运地址
     *                      public static final int TRANSPORT_LAND = 11;//陆运地址
     * @return
     */
    ResultDto checkRegionByCustomerId(String uid, Integer customerId, int transportType);


    /**
     * 订单产品初始化
     *
     * @param params
     * @return
     */
    QResultDto findByFilterForOrder(QueryParams params);

    /**
     * 根据主键Id查询产品范围
     *
     * @param id 主键id
     * @return 查询出来的产品范围
     */
    List<ProductRegionRel> getRegionByProductId(Integer id);

    /**
     * 根据主键Id产品计重规则
     *
     * @param id 主键id
     * @return 查询产品计重规则
     */
    ResultDto getWeightByProductId(Integer id);

    /**
     * 判断是不是主服务
     *
     * @param id
     * @return
     */
    Boolean checkMainService(Integer id);

    /**
     * 返回产品ids
     *
     * @param id
     * @return
     */
    List<Integer> findIds(Integer id);

    /**
     * 产品列表初始化，返回产品id, uid,名称
     *
     * @param params
     * @return
     */
    ResultDto findProductListReturnUidName(QueryParams params);

    /**
     * 根据uid查询产品
     *
     * @param uid
     * @return
     */
    ProductDto findByUid(String uid);

    /**
     * 根据uid查询产品的揽收服务的信息
     *
     * @param uid
     * @return
     */
    ProductReceiveInfoDto findProductReceiveInfoByUid(String uid);

    /**
     * 产品是否自动受理, true: 自动受理； false： 人工受理
     *
     * @param uid
     * @return
     */
    boolean isAcceptAuto(String uid);

    /**
     * 所有产品uid和name
     *
     * @param params
     * @return
     */
    List<Map<String, Object>> findProductListReturnUidNameAll(QueryParams params);

    /**
     * 私有产品组
     *
     * @return
     */
    List<Integer> privateProductGroups();

    /**
     * 返回产品组信息
     *
     * @param id
     * @return
     */
    ProductGroupInfo getProductGroupById(Integer id);

    /**
     * 返回产品所在组配置的货币类型
     *
     * @param productUid
     * @return
     */
    String getProductCurrencyByUid(String productUid);

    /**
     * 根据产品id和type查询服务范围的所有国家
     *
     * @param id
     * @param type
     * @param q
     * @param pageIndex
     * @param pageSize
     * @return
     */
    ResultDto getCountryByProductIdAndType(Integer id, String type, String q, int pageIndex, int pageSize);

    /**
     * 根据产品id,countryCode和type查询机场或港口，支持分页
     * 用于下单时，添加地址，选择国家、城市、港口/机场
     * @param id            --产品Id
     * @param countryCode   --国家编码
     * @param cityId        --城市Id
     * @param type          --字母区分的起点或重点类型：s-起点；e-终点
     * @param q             --搜索关键字
     * @param pageIndex     --分页
     * @param pageSize      --页面大小
     * @return
     */
    ResultDto getTransportByProductIdAndType(Integer id, String countryCode, String cityId, String type, String q, int pageIndex, int pageSize);

    /**
     * 根据产品id,type,countryCode和parentId查询地区
     *
     * @param id
     * @param countryCode
     * @param parentId
     * @param type
     * @param q
     * @param pageIndex
     * @param pageSize
     * @return
     */
    ResultDto getAreaByProductIdAndType(Integer id, String countryCode, String parentId, String type, String q, int pageIndex, int pageSize);

    /**
     * 产品服务范围
     *
     * @param uid
     * @param code
     * @param ordinal
     * @param hasDisabled
     * @return
     */
    ProductServiceRelDto findProductServiceRegions(String uid, String code, Integer ordinal, boolean hasDisabled);

    /**
     * 获取排除产品已有服务类型的其他服务类型
     *
     * @param productId
     * @return
     */
    List<SysDict> findServiceTypesExcludePrd(Integer productId);

    /**
     * 产品组信息、产品可选服务信息
     *
     * @param id
     * @return
     */
    ProductGroupOptServiceInfo getProductServiceInfos(Integer id);

    /**
     * 产品对客户的黑白名单
     *
     * @param customerId
     * @param pd
     * @return
     */
    ParamData populateCustomerProduct(Integer customerId, ParamData pd);

    /**
     * 根据产品名称或产品编码，账户id，查找用户可看到的产品信息，优先匹配产品编码对应的产品
     * 刘钏 负责
     */
    List<Product> findProductInfoByNameOrCode(String nameOrCode, Integer customerId);


    /**
     * 批量查找产品信息
     * @param nameOrCodes
     * @param customerId
     * @return
     */
    List<Product> findProductInfoByNameOrCodeList(List<String>  nameOrCodes, Integer customerId);
    /**
     * 根据产品的uid获取产品范围中的地址信息
     *
     * @param productUid 产品的uid
     * @return 产品的范围信息，包括发件人、收件人、揽收人
     */
    List<ProductAddressDto> getProductAddress(String productUid);

    /**
     * 根据指定类型获取相应类型的地址集合信息，并返回，如果未指定获取所有的信息返回
     *
     * @param productUid
     * @param addressType public final static String PRODUCT_SERVICE_REGION_START = "s";
     *                    public final static String PRODUCT_SERVICE_REGION_END = "e";
     *                    public final static String PRODUCT_SERVICE_REGION_PICKUP = "l";
     * @return 根据指定类型获取相应类型的地址集合信息，并返回，如果未指定获取所有的信息返回
     */
    List<ProductAddressDto> getProductAddress(String productUid, String addressType);

    /**
     * 根据指定的地址集合信息，判断指定的地址信息是否满足要求，如果满足，那么返回true，否则false
     *
     * @param addressDtoList 地址的集合信息
     * @param addressDto     要判断的地址信息
     * @return 如果满足，那么返回true，否则false
     */
    boolean checkProductAddress(List<ProductAddressDto> addressDtoList, ProductAddressDto addressDto);

    /**
     * 把指定的对象userAddressDto转换成对象ProductAddressDto
     *
     * @param transportType  public final static String PRODUCT_SERVICE_REGION_START = "s";
     *                       public final static String PRODUCT_SERVICE_REGION_END = "e";
     *                       public final static String PRODUCT_SERVICE_REGION_PICKUP = "l";
     * @param userAddressDto 用户的地址dto
     * @return
     */
    ProductAddressDto getProductAddressDto(int transportType, CusUserAddressDto userAddressDto);

    int getProductAcceptType(String productUid);

    /**
     * 使用产品的id获取产品的基本信息
     * @param productId
     * @return
     */
    Product findShortById(Integer productId);


    /**
     * 获取当前已启用的所有产品
     */
    List<Product> findAllOnlineProduct();

    /**
     * 根据产品的uid获取当前激活的产品对应的产品组信息
     * @param productUid 产品的uid
     * @return 当前激活产品的产品组信息
     */
    ProductGroup findGroupByUid(String productUid);
    String findProductCurrencyCodeByUid(String productUid);

}
